package com.fbee.smartcommunities.core;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fbee.smartcommunities.utils.ExpansionRequest;
import com.fbee.smartcommunities.utils.JwtUtil;
import com.fbee.smartcommunities.vo.ResultVO;
import lombok.Setter;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * ClassName: com.fbee.smartcommunities.core
 * Datetime: 2024/8/16 下午4:28
 * Description:
 *
 * @author 汪佳泉
 * @version 1.0
 * @since 1.0
 */
@Component
@Setter
@Order(0)
@ConfigurationProperties(prefix = "filter.white")
public class TokenFilter implements Filter {

    // 存放放行的路径
    private List<String> urls;

    @Resource(name = "myRedis")
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private PathMatcher pathMatcher;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            String token = httpServletRequest.getHeader("token");
            String uri = httpServletRequest.getRequestURI();
            // System.out.println(uri);
            if("OPTIONS".equals(httpServletRequest.getMethod())){
                chain.doFilter(httpServletRequest,httpServletResponse);
                return;
            }
            for( String url : urls){
                if(pathMatcher.match(url,uri)){
                    chain.doFilter(httpServletRequest,httpServletResponse);
                    return;
                }
            }
            try {
                // 如果Token不对的话就会报错，直接跳转到下面的错误处理，包括两种情况 Token被删除，Token是伪造的
                Long id = JwtUtil.decode(token);
                if(!redisTemplate.hasKey("user::" + id + "::permission")){
                    error(httpServletResponse, ResultVO.unLogin("登入超时，请重新登入"));
                    return;
                }
                String resources = String.valueOf(redisTemplate.opsForValue().get("user::" + id + "::permission"));
                List<String> resourcesList = JSONObject.parseArray(resources, String.class);
                for (String url : resourcesList) {
                    if(pathMatcher.match(url,uri)){
                        ExpansionRequest expansionRequest = new ExpansionRequest(httpServletRequest);
                        expansionRequest.addParameter("openId",id);
                        chain.doFilter(expansionRequest,httpServletResponse);
                        return;
                    }
                }
                error(httpServletResponse,ResultVO.forbid());
            } catch (Exception e) {
                error(httpServletResponse,ResultVO.unLogin(e.getMessage()));
            }

        }
    }

    private void error(HttpServletResponse response,ResultVO resultVO) throws IOException {
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        ObjectMapper objectMapper = new ObjectMapper();
        // 项目部署的时候需要更改
        response.setHeader("Access-Control-Allow-Origin", "http://localhost");
        response.getWriter().write(objectMapper.writeValueAsString(resultVO));
    }

}
